package com.xzzz.irda.tracker.server;

import cn.hutool.core.collection.CollUtil;
import com.xzzz.common.base.pojo.PageRes;
import com.xzzz.common.base.pojo.R;
import com.xzzz.irda.tracker.core.SpanNode;
import com.xzzz.irda.tracker.server.pojo.SpanNodeTermsRes;
import com.xzzz.irda.tracker.server.pojo.SpanNodeTreeRes;
import com.xzzz.irda.tracker.server.pojo.TraceDetailRes;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 链路追踪接口
 */
@Slf4j
@RestController
@RequestMapping("/tracker/metric")
public class TrackerMetricController {

    @Autowired(required = false)
    private TrackerMetricService trackerService;

    /**
     * 新增span信息
     *
     * @param spanNodes span节点信息
     */
    @PostMapping
    public R<?> addBatch(@RequestBody List<SpanNode> spanNodes) {
        if (trackerService == null) {
            return R.ok();
        }
        if (CollUtil.isNotEmpty(spanNodes)) {
            trackerService.saveBatch(spanNodes);
        }
        return R.ok();
    }

    /**
     * 查询Trace分页列表
     *
     * @param pageNum  当前页
     * @param pageSize 当前行数
     * @param appName  应用名称
     * @param traceId  追踪ID
     * @return
     */
    @GetMapping("/page")
    public R<PageRes<SpanNode>> page(
            @RequestParam Integer pageNum,
            @RequestParam Integer pageSize,
            @RequestParam(required = false) String appName,
            @RequestParam(required = false) String traceId) {
        return R.ok(trackerService.pages(pageNum, pageSize, appName, traceId));
    }

    /**
     * 根据 traceId 分组聚合查询
     *
     * @param pageSize 页数
     * @param appName  应用名称
     * @param traceId  追踪ID
     */
    @GetMapping("/page/termsTraceId")
    public R<List<SpanNodeTermsRes>> listGroupByTraceId(
            @RequestParam Integer pageSize,
            @RequestParam(required = false) String appName,
            @RequestParam(required = false) String traceId) {
        return R.ok(trackerService.listGroupByTraceId(pageSize, appName, traceId));
    }

    /**
     * 根据 TraceId 查询 Span 列表
     *
     * @param traceId traceId
     * @return Span列表
     */
    @GetMapping("/spans")
    public R<TraceDetailRes> spanList(String traceId) {
        List<SpanNode> spanNodes = trackerService.list(traceId);
        Map<String, List<SpanNode>> appCounts = spanNodes.stream().collect(Collectors.groupingBy(SpanNode::getAppName));

        TraceDetailRes res = new TraceDetailRes();
        res.setSpans(spanNodes);

        List<Map<String, Object>> appAggs = new ArrayList<>();
        appCounts.forEach((appName, spans) -> {
            Map<String, Object> app = new HashMap<>();
            app.put("name", appName + "(" + spans.size() + ")");
            app.put("value", spans.size());
            app.put("appName", appName);
            appAggs.add(app);
        });
        res.setAppAggs(appAggs);
        return R.ok(res);
    }

    /**
     * 根据 TraceId 查询 Span 树状列表
     *
     * @param traceId traceId
     * @return Span列表
     */
    @GetMapping("/spans/tree")
    public R<List<SpanNodeTreeRes>> spanListTree(String traceId) {
        List<SpanNode> spanList = this.spanList(traceId).getData().getSpans();
        return R.ok(TrackerTreeUtil.treeWrap(spanList));
    }

}
